%macro C 0
	enter 0,0
	push esi
	push edi
	push ebx
%endmacro
%macro endC 0
	push ebx
	push edi
	push esi
	leave
	ret
%endmacro

section .data


section .text
extern malloc
extern free
global suma
global sumaYResta
global prodInterno
global promedioVecinos
global productoEscalar
global normalizar
global productoInterno

suma:
	C
	mov edi,[ebp+8]
	mov esi,[ebp+12]
	xor ecx,ecx
	xor edx,edx
	mov dx,[ebp+16]
	lea edx,[edx*4]
	.loop:
		movq mm0,[edi+ecx]
		movq mm1,[esi+ecx]
		paddd mm0,mm1
		movq [edi+ecx],mm0
		lea ecx,[ecx+8]
		cmp ecx,edx
		jb .loop
	emms
	endC

sumaYResta:
	C
	mov ax,[ebp+16]
	shr ax,1
	push word ax
	call malloc
	mov edi,[ebp+8]
	mov esi,[ebp+12]
	xor ecx,ecx
	mov cx,[ebp+16]
	shr ecx,2
	inc ecx
	.loop:
		movq mm0,[edi+ecx*8-8]
		movq mm1,[esi+ecx*8-8]
		paddw mm0,mm1
		movq [eax+ecx*8-8],mm0
		loop .loop
	emms
	endC

prodInterno:
	C
	emms
	mov edi,[ebp+8]
	mov esi,[ebp+12]
	xor eax,eax
	xor ecx,ecx
	mov cx,[ebp+16]
	shr ecx,2
	;inc ecx
	xor edx,edx
	.loop:
		movq mm0,[edi+edx*2]
		movq mm1,[esi+edx]
		pxor mm2,mm2
		punpcklbw mm1,mm2
		pmullw mm0,mm1
		;phaddw mm2,mm0
			movq mm2,mm0
			pshufw mm2,mm2,01001110B;
			paddw mm2,mm0
		pxor mm0,mm0
		;phaddw mm2,mm0
			movq mm3,mm2
			pshufw mm3,mm3,10110001B
			paddw mm2,mm3
		movd ebx,mm2
		shl ebx,16
		sar ebx,16
		add eax,ebx
		lea edx,[edx+4]
		loop .loop
	emms
	endC

promedioVecinos:
	C
	xor eax,eax
	mov ax,[ebp+12]
	push eax
	mul eax
	push eax
	call malloc
	mov edi,eax
	pop eax
	pop ecx
	push edi			;pila=B*
	mov esi,[ebp+8];esi=A*
	push ecx			;pila=n|B*
	xor ecx,ecx
	xor ebx,ebx
	.loop:
		cmp ecx,0
		je .igual
		mov eax,[esp]
		dec eax
		cmp ecx,eax
		je .igual
		cmp ebx,0
		je .igual
		cmp ebx,eax
		je .igual
		;promedio...
		xor edx,edx
		xor eax,eax
		mov dx,[esi+ecx*2+2]
		add eax,edx
		mov dx,[esi+ecx*2-2]
		add eax,edx
		push esi
		sub esi,[esp+4]
		sub esi,[esp+4]
		mov dx,[esi+ecx*2]
		add eax,edx
		pop esi
		push esi
		add esi,[esp+4]
		add esi,[esp+4]
		mov dx,[esi+ecx*2]
		add eax,edx
		pop esi
		shr eax,2
		mov word [edi+ecx*2],ax
		jmp .ok
		.igual:
		mov ax,[esi+ecx*2]
		mov word [edi+ecx*2],ax
		.ok:
		inc ecx
		cmp [esp],ecx
		ja .loop
	mov ecx,[esp]
	sal ecx,1
	add edi,ecx
	add esi,ecx
	xor ecx,ecx
	inc ebx
	cmp [esp],ebx
	ja .loop
	pop eax
	pop eax
	endC

productoEscalar:
	C
	xor eax,eax
	mov ax,[ebp+16]
	sal eax,2
	push eax
	call malloc
	mov edi,eax
	mov esi,[ebp+8]
	movss xmm0,[ebp+12]
	pshufd xmm0,xmm0,0
	xor ecx,ecx
	mov cx,[ebp+16]
	shr ecx,2
	inc ecx
	.loop:
		movups xmm1,[esi+ecx*8-8]
		mulps xmm1,xmm0
		movups [edi+ecx*8-8],xmm1
		loop .loop
	emms
	endC

normalizar:
	C
	xor eax,eax
	mov ax,[ebp+12]
	shl eax,2
	call malloc
	mov edi,eax
	mov esi,[ebp+8]
	xor ecx,ecx
	mov cx,[ebp+12]
	shr ecx,2
	push ecx
	xor ebx,ebx
	pxor xmm1,xmm1
	.loop:
		cvtpi2ps xmm0,[esi+ebx+8]
		pshufd xmm0,xmm0,01001110B
		cvtpi2ps xmm0,[esi+ebx]
		movups [edi+ebx],xmm0
		mulps xmm0,xmm0
		addps xmm1,xmm0
		lea ebx,[ebx+16]
		loop .loop
	haddps xmm1,xmm1
	haddps xmm1,xmm1
	pshufd xmm1,xmm1,0
	sqrtps xmm1,xmm1
	xor ebx,ebx
	pop ecx
	.loop2:
		movups xmm0,[edi+ebx]
		divps xmm0,xmm1
		movups [edi+ebx],xmm0
		lea ebx,[ebx+16]
		loop .loop2
	mov eax,edi
	endC

productoInterno:
	C
	finit
	mov edi,[ebp+8]
	mov esi,[ebp+12]
	xor ecx,ecx
	mov cx,[ebp+16]
	shr ecx,2
	xor edx,edx
	pxor xmm2,xmm2
	.loop:
		movups xmm0,[edi+edx]
		movups xmm1,[esi+edx]
		mulps xmm0,xmm1
		haddps xmm0,xmm0
		haddps xmm0,xmm0
		addss xmm2,xmm0
		lea edx,[edx+16]
		loop .loop
	movss [esp-4],xmm2
	finit
	fld dword [esp-4]
	endC
